local_edition(3)
skip_on_cran()

# Create a table based on `sp500`, with
# group names, rownames, and four
# columns of values
tbl <-
  sp500 %>%
  dplyr::filter(
    date >= "2015-01-05" &
      date <="2015-01-16"
  ) %>%
  dplyr::arrange(date) %>%
  dplyr::mutate(
    week = paste0(
      "W", strftime(date, format = "%V"))
  ) %>%
  dplyr::select(-adj_close, -volume) %>%
  gt(
    rowname_col = "date",
    groupname_col = "week"
  )

# Gets the inner HTML text from a single value
selection_text <- function(html, selection) {

  html %>%
    rvest::html_nodes(selection) %>%
    rvest::html_text()
}

test_that("the `summary_rows()` can make groupwise summaries", {

  # Create a table with summary rows for
  # the `W02` group; the 3 summary rows for
  # this group represent the mean, sum,
  # and standard deviation of all numeric
  # columns
  gt_tbl <-
    tbl %>%
    summary_rows(
      groups = "W02",
      columns = c(open, high, low, close),
      fns = list(
        average = ~mean(., na.rm = TRUE),
        total = ~sum(., na.rm = TRUE),
        `std dev` = ~sd(., na.rm = TRUE)
      )
    )

  # Extract the internal `summary` object
  summary <- dt_summary_get(data = gt_tbl)

  # Expect that the internal `summary` list
  # object has a length of `1` since there was
  # only one call of `summary_rows()`
  length(summary) %>% expect_equal(1)

  # For the single list component in `summary`, expect specific
  # names within it
  summary[[1]] %>%
    names() %>%
    expect_equal(
      c(
        "groups", "columns", "fns", "summary_labels",
        "missing_text", "formatter", "formatter_options"
      )
    )

  # Expect the `groups` provided in `summary[[1]]$groups`
  summary[[1]]$groups %>% expect_equal("W02")

  # Expect the `columns` provided in `summary[[1]]$columns`
  summary[[1]]$columns %>% expect_equal(c("open", "high", "low", "close"))

  # Expect that `summary[[1]]$fns` is a `list` object
  summary[[1]]$fns %>% expect_type("list")

  # Expect that the components of `summary[[1]]$fns` are formulas
  summary[[1]]$fns$average %>% expect_s3_class("formula")
  summary[[1]]$fns$total %>% expect_s3_class("formula")
  summary[[1]]$fns$`std dev` %>% expect_s3_class("formula")

  # Expect that `summary[[1]]$missing_text` has a specific value
  summary[[1]]$missing_text %>% expect_equal("---")

  # Expect that `summary[[1]]$formatter` is a `function` object
  expect_equal(class(summary[[1]]$formatter), "function")

  # Expect that `summary[[1]]$formatter_options` is a list
  expect_type(summary[[1]]$formatter_options, "list")

  # Expect that `summary[[1]]$formatter_options` is
  # of length 0
  summary[[1]]$formatter_options %>% length() %>% expect_equal(0)

  # Create a table with summary rows for
  # the `W02` group; the 3 summary rows for
  # this group represent the mean, sum,
  # and standard deviation of only the
  # `open` column
  gt_tbl <-
    tbl %>%
    summary_rows(
      groups = "W02",
      columns = open,
      fns = list(
        average = ~mean(., na.rm = TRUE),
        total = ~sum(., na.rm = TRUE),
        `std dev` = ~sd(., na.rm = TRUE)
      )
    )

  # Extract the internal `summary` object
  summary <- dt_summary_get(data = gt_tbl)

  # Expect the `groups` provided in `summary[[1]]$groups`
  summary[[1]]$groups %>% expect_equal("W02")

  # Expect the `columns` provided in `summary[[1]]$columns`
  summary[[1]]$columns %>% expect_equal("open")

  # Expect that `summary[[1]]$fns` is a `list` object
  summary[[1]]$fns %>% expect_type("list")

  # Expect that the components of `summary[[1]]$fns` are formulas
  summary[[1]]$fns$average %>% expect_s3_class("formula")
  summary[[1]]$fns$total %>% expect_s3_class("formula")
  summary[[1]]$fns$`std dev` %>% expect_s3_class("formula")

  # Expect that `summary[[1]]$missing_text` has a specific value
  summary[[1]]$missing_text %>%expect_equal("---")

  # Expect that `summary[[1]]$formatter` is a `function` object
  expect_equal(class(summary[[1]]$formatter), "function")

  # Expect that `summary[[1]]$formatter_options` is a list
  summary[[1]]$formatter_options %>% expect_type("list")

  # Expect that `summary[[1]]$formatter_options` is
  # of length 0
  summary[[1]]$formatter_options %>%
    length() %>%
    expect_equal(0)

  # Create a table with summary rows for
  # the `W02` and `W03` groups; the 3 summary
  # rows for these groups represent the mean,
  # sum, and standard deviation of only the
  # `open` column
  gt_tbl <-
    tbl %>%
    summary_rows(
      groups = c("W02", "W03"),
      columns = open,
      fns = list(
        average = ~mean(., na.rm = TRUE),
        total = ~sum(., na.rm = TRUE),
        `std dev` = ~sd(., na.rm = TRUE)
      )
    )

  # Extract the internal `summary` object
  summary <- dt_summary_get(data = gt_tbl)

  # Expect the `groups` provided in `summary[[1]]$groups`
  summary[[1]]$groups %>% expect_equal(c("W02", "W03"))

  # Expect the `columns` provided in `summary[[1]]$columns`
  summary[[1]]$columns %>% expect_equal("open")

  # Expect that `summary[[1]]$fns` is a `list` object
  summary[[1]]$fns %>% expect_type("list")

  # Expect that the components of `summary[[1]]$fns` are formulas
  summary[[1]]$fns$average %>% expect_s3_class("formula")
  summary[[1]]$fns$total %>% expect_s3_class("formula")
  summary[[1]]$fns$`std dev` %>% expect_s3_class("formula")

  # Expect that `summary[[1]]$missing_text` has a specific value
  summary[[1]]$missing_text %>% expect_equal("---")

  # Expect that `summary[[1]]$formatter` is a `function` object
  expect_equal(class(summary[[1]]$formatter), "function")

  # Expect that `summary[[1]]$formatter_options` is a list
  summary[[1]]$formatter_options %>% expect_type("list")

  # Expect that `summary[[1]]$formatter_options` is
  # of length 0
  summary[[1]]$formatter_options %>%
    length() %>%
    expect_equal(0)

  # Create a table with summary rows for
  # the `W02` and `W03` groups (using
  # `groups = TRUE`); the 3 summary rows for
  # these groups represent the mean,
  # sum, and standard deviation of only the
  # `open` column
  gt_tbl <-
    tbl %>%
    summary_rows(
      groups = TRUE,
      columns = open,
      fns = list(
        average = ~mean(., na.rm = TRUE),
        total = ~sum(., na.rm = TRUE),
        `std dev` = ~sd(., na.rm = TRUE)
      )
    )

  # Extract the internal `summary` object
  summary <- dt_summary_get(data = gt_tbl)

  # Expect the `groups` provided in `summary[[1]]$groups`
  # to be `TRUE`
  summary[[1]]$groups %>% expect_true()

  # Expect the `columns` provided in `summary[[1]]$columns`
  summary[[1]]$columns %>% expect_equal("open")

  # Expect that `summary[[1]]$fns` is a `list` object
  summary[[1]]$fns %>% expect_type("list")

  # Expect that the components of `summary[[1]]$fns` are formulas
  summary[[1]]$fns$average %>% expect_s3_class("formula")
  summary[[1]]$fns$total %>% expect_s3_class("formula")
  summary[[1]]$fns$`std dev` %>% expect_s3_class("formula")

  # Expect that `summary[[1]]$missing_text` has a specific value
  summary[[1]]$missing_text %>% expect_equal("---")

  # Expect that `summary[[1]]$formatter` is a `function` object
  expect_equal(class(summary[[1]]$formatter), "function")

  # Expect that `summary[[1]]$formatter_options` is a list
  summary[[1]]$formatter_options %>% expect_type("list")

  # Expect that `summary[[1]]$formatter_options` is
  # of length 0
  summary[[1]]$formatter_options %>% length() %>% expect_equal(0)

  # Create a table with two sets of summary rows for all groups
  # and all columns
  gt_tbl <-
    tbl %>%
    summary_rows(
      groups = TRUE,
      columns = c(open, high, low, close),
      fns = list(
        average = ~mean(., na.rm = TRUE),
        total = ~sum(., na.rm = TRUE),
        `std dev` = ~sd(., na.rm = TRUE)
      )
    ) %>%
    summary_rows(
      groups = TRUE,
      columns = c(open, high, low, close),
      fns = list(
        max = ~max(., na.rm = TRUE)
      )
    )

  # Extract the internal `summary` object
  summary <- dt_summary_get(data = gt_tbl)

  # Expect that the internal `summary` list
  # object has a length of `2` since there
  # were two calls of `summary_rows()`
  length(summary) %>%
    expect_equal(2)

  # For the two list components in `summary`, expect specific
  # names within them
  summary[[1]] %>%
    names() %>%
    expect_equal(
      c(
        "groups", "columns", "fns", "summary_labels",
        "missing_text", "formatter", "formatter_options"
      )
    )

  summary[[2]] %>%
    names() %>%
    expect_equal(
      c(
        "groups", "columns", "fns", "summary_labels",
        "missing_text", "formatter", "formatter_options"
      )
    )

  # Expect that `summary[[1|2]]$groups` is TRUE
  summary[[1]]$groups %>% expect_true()

  summary[[2]]$groups %>% expect_true()

  # Expect that `summary[[1|2]]$columns` has specific values
  summary[[1]]$columns %>%
    expect_equal(c("open", "high", "low", "close"))

  summary[[2]]$columns %>%
    expect_equal(c("open", "high", "low", "close"))

  # Expect that `summary[[1|2]]$fns` is a `list` object
  summary[[1]]$fns %>% expect_type("list")

  summary[[2]]$fns %>% expect_type("list")

  # Expect that the components of `summary[[1|2]]$fns` are formulas
  summary[[1]]$fns$average %>% expect_s3_class("formula")
  summary[[1]]$fns$total %>% expect_s3_class("formula")
  summary[[1]]$fns$`std dev` %>% expect_s3_class("formula")
  summary[[2]]$fns$max %>% expect_s3_class("formula")

  # Expect that `summary[[1|2]]$missing_text` has a specific value
  summary[[1]]$missing_text %>% expect_equal("---")

  summary[[2]]$missing_text %>% expect_equal("---")

  # Expect that `summary[[1|2]]$formatter` is a `function` object
  expect_equal(class(summary[[1]]$formatter), "function")
  expect_equal(class(summary[[2]]$formatter), "function")

  # Expect that `summary[[1|2]]$formatter_options` is a list
  summary[[1]]$formatter_options %>% expect_type("list")
  summary[[2]]$formatter_options %>% expect_type("list")

  # Expect that `summary[[1|2]]$formatter_options` are both
  # of length 0
  summary[[1]]$formatter_options %>% length() %>% expect_equal(0)
  summary[[2]]$formatter_options %>% length() %>% expect_equal(0)

  # Create a table with two sets of summary rows for all groups
  # and all columns
  gt_tbl <-
    tbl %>%
    summary_rows(
      groups = TRUE,
      columns = c(open, high),
      fns = list(
        average = ~mean(., na.rm = TRUE),
        total = ~sum(., na.rm = TRUE),
        `std dev` = ~sd(., na.rm = TRUE)
      )
    ) %>%
    summary_rows(
      groups = TRUE,
      columns = c(low, close),
      fns = list(
        average = ~mean(., na.rm = TRUE),
        total = ~sum(., na.rm = TRUE),
        `std dev` = ~sd(., na.rm = TRUE)
      )
    )

  # Extract the internal `summary` object
  summary <- dt_summary_get(data = gt_tbl)

  # Expect that the internal `summary` list
  # object has a length of `2` since there
  # were two calls of `summary_rows()`
  length(summary) %>% expect_equal(2)

  # For the two list components in `summary`, expect specific
  # names within them
  summary[[1]] %>%
    names() %>%
    expect_equal(
      c(
        "groups", "columns", "fns", "summary_labels",
        "missing_text", "formatter", "formatter_options"
      )
    )

  summary[[2]] %>%
    names() %>%
    expect_equal(
      c(
        "groups", "columns", "fns", "summary_labels",
        "missing_text", "formatter", "formatter_options"
      )
    )

  # Expect that `summary[[1|2]]$groups` is TRUE
  summary[[1]]$groups %>% expect_true()
  summary[[2]]$groups %>% expect_true()

  # Expect that `summary[[1|2]]$columns` has specific values
  summary[[1]]$columns %>% expect_equal(c("open", "high"))
  summary[[2]]$columns %>% expect_equal(c("low", "close"))

  # Expect that `summary[[1|2]]$fns` is a `list` object
  summary[[1]]$fns %>% expect_type("list")
  summary[[2]]$fns %>% expect_type("list")

  # Expect that the components of `summary[[1|2]]$fns` are formulas
  summary[[1]]$fns$average %>% expect_s3_class("formula")
  summary[[1]]$fns$total %>% expect_s3_class("formula")
  summary[[1]]$fns$`std dev` %>% expect_s3_class("formula")
  summary[[2]]$fns$average %>% expect_s3_class("formula")
  summary[[2]]$fns$total %>% expect_s3_class("formula")
  summary[[2]]$fns$`std dev` %>% expect_s3_class("formula")

  # Expect that `summary[[1|2]]$missing_text` has a specific value
  summary[[1]]$missing_text %>% expect_equal("---")
  summary[[2]]$missing_text %>% expect_equal("---")

  # Expect that `summary[[1|2]]$formatter` is a `function` object
  expect_equal(class(summary[[1]]$formatter), "function")
  expect_equal(class(summary[[2]]$formatter), "function")

  # Expect that `summary[[1|2]]$formatter_options` is a list
  summary[[1]]$formatter_options %>% expect_type("list")
  summary[[2]]$formatter_options %>% expect_type("list")

  # Expect that `summary[[1|2]]$formatter_options` are both
  # of length 0
  summary[[1]]$formatter_options %>% length() %>% expect_equal(0)
  summary[[2]]$formatter_options %>% length() %>% expect_equal(0)
})

test_that("the `summary_rows()` can make grand summaries", {

  # Create a table with a grand summary;
  # the 3 summary rows for represent the
  # mean, sum, and standard deviation of
  # all numeric columns
  gt_tbl <-
    tbl %>%
    summary_rows(
      groups = NULL,
      columns = c(open, high, low, close),
      fns = list(
        average = ~mean(., na.rm = TRUE),
        total = ~sum(., na.rm = TRUE),
        `std dev` = ~sd(., na.rm = TRUE)
      )
    )

  # Extract the internal `summary` object
  summary <- dt_summary_get(data = gt_tbl)

  # Expect that the internal `summary` list
  # object has a length of `1` since there was
  # only one call of `summary_rows()`
  length(summary) %>%
    expect_equal(1)

  # For the single list component in `summary`, expect specific
  # names within it
  summary[[1]] %>%
    names() %>%
    expect_equal(
      c(
        "groups", "columns", "fns", "summary_labels",
        "missing_text", "formatter", "formatter_options"
      )
    )

  # Expect the `groups` provided in `summary[[1]]$groups`
  # is NULL
  summary[[1]]$groups %>% expect_null()

  # Expect the `columns` provided in `summary[[1]]$columns`
  # provide names for all columns
  summary[[1]]$columns %>% expect_equal(c("open", "high", "low", "close"))

  # Expect that `summary[[1]]$fns` is a `list` object
  summary[[1]]$fns %>% expect_type("list")

  # Expect that the components of `summary[[1]]$fns` are formulas
  summary[[1]]$fns$average %>% expect_s3_class("formula")
  summary[[1]]$fns$total %>% expect_s3_class("formula")
  summary[[1]]$fns$`std dev` %>% expect_s3_class("formula")

  # Expect that `summary[[1]]$missing_text` has a specific value
  summary[[1]]$missing_text %>% expect_equal("---")

  # Expect that `summary[[1]]$formatter` is a `function` object
  expect_equal(class(summary[[1]]$formatter), "function")

  # Expect that `summary[[1]]$formatter_options` is a list
  summary[[1]]$formatter_options %>% expect_type("list")

  # Create a table with a grand summary;
  # the 3 summary rows for represent the
  # mean, sum, and standard deviation of
  # all numeric columns; split into 2 calls
  # that allow for different formatting
  # options
  gt_tbl <-
    tbl %>%
    summary_rows(
      groups = NULL,
      columns = c(open, high),
      fns = list(
        average = ~mean(., na.rm = TRUE),
        total = ~sum(., na.rm = TRUE),
        `std dev` = ~sd(., na.rm = TRUE)),
      formatter = fmt_number,
      decimals = 3
    ) %>%
    summary_rows(
      groups = NULL,
      columns = c(low, close),
      fns = list(
        average = ~mean(., na.rm = TRUE),
        total = ~sum(., na.rm = TRUE),
        `std dev` = ~sd(., na.rm = TRUE)),
      formatter = fmt_number,
      decimals = 5
    )

  # Extract the internal `summary` object
  summary <- dt_summary_get(data = gt_tbl)

  # Expect that the internal `summary` list
  # object has a length of `2` since there
  # were two calls of `summary_rows()`
  length(summary) %>% expect_equal(2)

  # For the two list components in `summary`, expect specific
  # names within them
  summary[[1]] %>%
    names() %>%
    expect_equal(
      c(
        "groups", "columns", "fns", "summary_labels",
        "missing_text", "formatter", "formatter_options"
      )
    )

  summary[[2]] %>%
    names() %>%
    expect_equal(
      c(
        "groups", "columns", "fns", "summary_labels",
        "missing_text", "formatter", "formatter_options"
      )
    )

  # Expect that `summary[[1|2]]$groups` is TRUE
  summary[[1]]$groups %>% expect_null()
  summary[[2]]$groups %>% expect_null()

  # Expect that `summary[[1|2]]$columns` has specific values
  summary[[1]]$columns %>% expect_equal(c("open", "high"))
  summary[[2]]$columns %>% expect_equal(c("low", "close"))

  # Expect that `summary[[1|2]]$fns` is a `list` object
  summary[[1]]$fns %>% expect_type("list")
  summary[[2]]$fns %>% expect_type("list")

  # Expect that the functions used in each call
  # are the same
  expect_identical(summary[[1]]$fns, summary[[1]]$fns)

  # Expect that the components of `summary[[1|2]]$fns` are formulas
  summary[[1]]$fns$average %>% expect_s3_class("formula")
  summary[[1]]$fns$total %>% expect_s3_class("formula")
  summary[[1]]$fns$`std dev` %>% expect_s3_class("formula")
  summary[[2]]$fns$average %>% expect_s3_class("formula")
  summary[[2]]$fns$total %>% expect_s3_class("formula")
  summary[[2]]$fns$`std dev` %>% expect_s3_class("formula")

  # Expect that `summary[[1|2]]$missing_text` has a specific value
  summary[[1]]$missing_text %>% expect_equal("---")
  summary[[2]]$missing_text %>% expect_equal("---")

  # Expect that `summary[[1|2]]$formatter` is a `function` object
  expect_equal(class(summary[[1]]$formatter), "function")
  expect_equal(class(summary[[2]]$formatter), "function")

  # Expect that the formatters used in each call
  # are the same
  expect_identical(summary[[1]]$formatter, summary[[2]]$formatter)

  # Expect that `summary[[1|2]]$formatter_options` is a list
  summary[[1]]$formatter_options %>% expect_type("list")
  summary[[2]]$formatter_options %>% expect_type("list")

  # Expect that `summary[[1|2]]$formatter_options` are both
  # of length 1
  summary[[1]]$formatter_options %>% length() %>% expect_equal(1)
  summary[[2]]$formatter_options %>% length() %>% expect_equal(1)

  # Expect that `summary[[1|2]]$formatter_options`
  # are both named `decimals`
  summary[[1]]$formatter_options %>%
    names() %>%
    expect_equal("decimals")

  summary[[2]]$formatter_options %>%
    names() %>%
    expect_equal("decimals")

  # Expect that the `summary[[1|2]]$formatter_options`
  # `decimals` options have specific values
  summary[[1]]$formatter_options[[1]] %>% expect_equal(3)
  summary[[2]]$formatter_options[[1]] %>% expect_equal(5)

  # Create a table with groupwsie summaries
  # and a grand summary; all summary rows
  # represent the mean, sum, and standard
  # deviation of all numeric columns;
  gt_tbl <-
    tbl %>%
    summary_rows(
      groups = TRUE,
      columns = c(open, high, low, close),
      fns = list(
        average = ~mean(., na.rm = TRUE),
        total = ~sum(., na.rm = TRUE),
        `std dev` = ~sd(., na.rm = TRUE)
      )
    ) %>%
    summary_rows(
      groups = NULL,
      columns = c(open, high, low, close),
      fns = list(
        average = ~mean(., na.rm = TRUE),
        total = ~sum(., na.rm = TRUE),
        `std dev` = ~sd(., na.rm = TRUE)
      )
    )

  # Extract the internal `summary` object
  summary <- dt_summary_get(data = gt_tbl)

  # Expect that the internal `summary` list
  # object has a length of `2` since there
  # were two calls of `summary_rows()`
  length(summary) %>% expect_equal(2)

  # For the two list components in `summary`, expect specific
  # names within them
  summary[[1]] %>%
    names() %>%
    expect_equal(
      c(
        "groups", "columns", "fns", "summary_labels",
        "missing_text", "formatter", "formatter_options"
      )
    )

  summary[[2]] %>%
    names() %>%
    expect_equal(
      c(
        "groups", "columns", "fns", "summary_labels",
        "missing_text", "formatter", "formatter_options"
      )
    )

  # Expect that `summary[[1]]$groups` is TRUE
  summary[[1]]$groups %>% expect_true()

  # Expect that `summary[[2]]$groups` is NULL
  summary[[2]]$groups %>% expect_null()

  # Expect that `summary[[1|2]]$columns` has specific values
  summary[[1]]$columns %>% expect_equal(c("open", "high", "low", "close"))
  summary[[2]]$columns %>% expect_equal(c("open", "high", "low", "close"))

  # Expect that `summary[[1|2]]$fns` is a `list` object
  summary[[1]]$fns %>% expect_type("list")
  summary[[2]]$fns %>% expect_type("list")

  # Expect that the functions used in each call
  # are the same
  expect_identical(summary[[1]]$fns, summary[[1]]$fns)

  # Expect that the components of `summary[[1|2]]$fns` are formulas
  summary[[1]]$fns$average %>% expect_s3_class("formula")
  summary[[1]]$fns$total %>% expect_s3_class("formula")
  summary[[1]]$fns$`std dev` %>% expect_s3_class("formula")
  summary[[2]]$fns$average %>% expect_s3_class("formula")
  summary[[2]]$fns$total %>% expect_s3_class("formula")
  summary[[2]]$fns$`std dev` %>% expect_s3_class("formula")

  # Expect that `summary[[1|2]]$missing_text` has a specific value
  summary[[1]]$missing_text %>% expect_equal("---")
  summary[[2]]$missing_text %>% expect_equal("---")

  # Expect that `summary[[1|2]]$formatter` is a `function` object
  expect_equal(class(summary[[1]]$formatter), "function")
  expect_equal(class(summary[[2]]$formatter), "function")

  # Expect that the formatters used in each call
  # are the same
  expect_identical(summary[[1]]$formatter, summary[[2]]$formatter)

  # Expect that `summary[[1|2]]$formatter_options` is a list
  summary[[1]]$formatter_options %>% expect_type("list")
  summary[[2]]$formatter_options %>% expect_type("list")

  # Expect that `summary[[1|2]]$formatter_options` are both
  # of length 0
  summary[[1]]$formatter_options %>% length() %>% expect_equal(0)
  summary[[2]]$formatter_options %>% length() %>% expect_equal(0)
})

test_that("`groups = FALSE` returns data unchanged", {

  # Expect that using `groups = FALSE` with
  # `summary_rows()` creates no summary rows
  expect_equal(
    tbl %>% as_raw_html(),
    tbl %>%
      summary_rows(
        groups = FALSE,
        columns = c(open, high, low, close),
        fns = list(
          average = ~mean(., na.rm = TRUE),
          total = ~sum(., na.rm = TRUE),
          `std dev` = ~sd(., na.rm = TRUE)
        )
      ) %>%
      as_raw_html()
  )
})

test_that("the ordering of groups shouldn't affect group/grand summary calcs", {

  # Create tibbles with rows in different orders
  tbl_1 <-
    tibble::tibble(
      id = c("1", "2", "3", "4", "5", "6"),
      value = c(1, 10, 1, 10, 99, 1),
      group = c("b", "a", "b", "a", "c", "b")
    )

  tbl_2 <-
    tbl_1 %>%
    dplyr::slice(6, 3, 5, 1, 4, 2)

  tbl_3 <-
    tbl_2 %>%
    dplyr::arrange(group, id)

  # Prepare a set gt tables with summary rows (using the same
  # `summary_rows()` call each time)
  gt_tbl_1 <-
    tbl_1 %>%
    dplyr::group_by(group) %>%
    gt(rowname_col = "id") %>%
    summary_rows(groups = TRUE, columns = value, fns = list("sum"))

  gt_tbl_1b <-
    tbl_1 %>%
    gt(rowname_col = "id", groupname_col = "group") %>%
    summary_rows(groups = TRUE, columns = value, fns = list("sum"))

  gt_tbl_2 <-
    tbl_2 %>%
    gt(rowname_col = "id", groupname_col = "group") %>%
    summary_rows(groups = TRUE, columns = value, fns = list("sum"))

  gt_tbl_3 <-
    tbl_3 %>%
    gt(rowname_col = "id", groupname_col = "group") %>%
    summary_rows(groups = TRUE, columns = value, fns = list("sum"))

  # Expect the correct values in summary rows of `gt_tbl`
  gt_tbl_1 %>% render_as_html() %>% xml2::read_html() %>%
    selection_text("[class='gt_row gt_right gt_summary_row gt_first_summary_row thick gt_last_summary_row']") %>%
    expect_equal(c("3.00", "20.00", "99.00"))

  # Expect the HTML output tables of `gt_tbl_1` and `gt_tbl_1b` to be the same
  expect_identical(
    gt_tbl_1 %>% render_as_html(),
    gt_tbl_1b %>% render_as_html()
  )

  # Expect the correct values in summary rows of `gt_tbl_2`
  gt_tbl_2 %>% render_as_html() %>% xml2::read_html() %>%
    selection_text("[class='gt_row gt_right gt_summary_row gt_first_summary_row thick gt_last_summary_row']") %>%
    expect_equal(c("3.00", "99.00", "20.00"))

  # Expect the correct values in summary rows of `gt_tbl_3`
  gt_tbl_3 %>% render_as_html() %>% xml2::read_html() %>%
    selection_text("[class='gt_row gt_right gt_summary_row gt_first_summary_row thick gt_last_summary_row']") %>%
    expect_equal(c("20.00", "3.00", "99.00"))

  # Prepare a set gt tables with a grand summary (using the same
  # `grand_summary_rows()` call each time)
  gt_tbl_1_gs <-
    tbl_1 %>%
    dplyr::group_by(group) %>%
    gt(rowname_col = "id") %>%
    grand_summary_rows(columns = value, fns = list("sum"))

  gt_tbl_1b_gs <-
    tbl_1 %>%
    gt(rowname_col = "id", groupname_col = "group") %>%
    grand_summary_rows(columns = value, fns = list("sum"))

  gt_tbl_2_gs <-
    tbl_2 %>%
    gt(rowname_col = "id", groupname_col = "group") %>%
    grand_summary_rows(columns = value, fns = list("sum"))

  gt_tbl_3_gs <-
    tbl_3 %>%
    gt(rowname_col = "id", groupname_col = "group") %>%
    grand_summary_rows(columns = value, fns = list("sum"))

  # Expect the correct value in the grand summary row of `gt_tbl_gs`
  gt_tbl_1_gs %>% render_as_html() %>% xml2::read_html() %>%
    selection_text("[class='gt_row gt_right gt_grand_summary_row gt_first_grand_summary_row gt_last_summary_row']") %>%
    expect_equal(c("122.00"))

  # Expect the HTML output tables of `gt_tbl_gs` and `gt_tbl_1b_gs` to be the same
  expect_identical(
    gt_tbl_1_gs %>% render_as_html(),
    gt_tbl_1b_gs %>% render_as_html()
  )

  # Expect the correct value in the grand summary row of `gt_tbl_2_gs`
  gt_tbl_2_gs %>% render_as_html() %>% xml2::read_html() %>%
    selection_text("[class='gt_row gt_right gt_grand_summary_row gt_first_grand_summary_row gt_last_summary_row']") %>%
    expect_equal(c("122.00"))

  # Expect the correct value in the grand summary row of `gt_tbl_3_gs`
  gt_tbl_3_gs %>% render_as_html() %>% xml2::read_html() %>%
    selection_text("[class='gt_row gt_right gt_grand_summary_row gt_first_grand_summary_row gt_last_summary_row']") %>%
    expect_equal(c("122.00"))

  # Example where a columns is named `columns`
  tbl_4 <-
    tibble::tibble(
      id = c("1", "2", "3", "4", "5", "6"),
      value = c(1, 10, 1, 10, 99, 1),
      columns = c(2, 20, 2, 20, 198, 2),
      group = c("b", "a", "b", "a", "c", "b")
    )

  gt_tbl_4 <-
    tbl_4 %>%
    dplyr::group_by(group) %>%
    gt(rowname_col = "id") %>%
    summary_rows(groups = TRUE, columns = c(value, columns), fns = list("sum")) %>%
    grand_summary_rows(columns = c(value, columns), fns = list("sum"))

  # Expect the correct values in summary rows of `gt_tbl_4`
  gt_tbl_4 %>% render_as_html() %>% xml2::read_html() %>%
    selection_text("[class='gt_row gt_right gt_summary_row gt_first_summary_row thick gt_last_summary_row']") %>%
    expect_equal(c("3.00", "6.00", "20.00", "40.00", "99.00", "198.00"))

  # Expect the correct values in the grand summary row of `gt_tbl_4`
  gt_tbl_4 %>% render_as_html() %>% xml2::read_html() %>%
    selection_text("[class='gt_row gt_right gt_grand_summary_row gt_first_grand_summary_row gt_last_summary_row']") %>%
    expect_equal(c("122.00", "244.00"))

  gt_tbl_5 <-
    tbl_4 %>%
    dplyr::rename(grand_summary_col = columns) %>%
    dplyr::group_by(group) %>%
    gt(rowname_col = "id") %>%
    summary_rows(groups = TRUE, columns = c(value, grand_summary_col), fns = list("sum")) %>%
    grand_summary_rows(columns = c(value, grand_summary_col), fns = list("sum"))

  # Expect the correct values in summary rows of `gt_tbl_4`
  gt_tbl_5 %>% render_as_html() %>% xml2::read_html() %>%
    selection_text("[class='gt_row gt_right gt_summary_row gt_first_summary_row thick gt_last_summary_row']") %>%
    expect_equal(c("3.00", "6.00", "20.00", "40.00", "99.00", "198.00"))

  # Expect the correct values in the grand summary row of `gt_tbl_4`
  gt_tbl_5 %>% render_as_html() %>% xml2::read_html() %>%
    selection_text("[class='gt_row gt_right gt_grand_summary_row gt_first_grand_summary_row gt_last_summary_row']") %>%
    expect_equal(c("122.00", "244.00"))
})

test_that("summary cells can be created with NA/NaN-resulting values", {

  # Generate a tibble with two columns containing just NA values
  na_tbl <-
    tibble::tibble(
      group = c(rep("one", 5), rep("two", 5)),
      na_1 = rep(NA_real_, 10),
      na_2 = rep(NA_integer_, 10)
    )

  # Create a gt table with summary rows
  gt_tbl_1 <-
    na_tbl %>%
    gt(groupname_col = "group") %>%
    summary_rows(
      groups = c("one", "two"),
      columns = c(na_1, na_2),
      fns = list(
        ~ sum(., na.rm = TRUE),
        ~ mean(., na.rm = TRUE)
      )
    )

  # Expect the correct values in all of the first and second
  # summary rows of `gt_tbl_1`
  gt_tbl_1 %>% render_as_html() %>% xml2::read_html() %>%
    selection_text("[class='gt_row gt_right gt_summary_row gt_first_summary_row thick']") %>%
    expect_equal(rep("0.00", 4))

  gt_tbl_1 %>% render_as_html() %>% xml2::read_html() %>%
    selection_text("[class='gt_row gt_right gt_summary_row gt_last_summary_row']") %>%
    expect_equal(rep("—", 4))

  # Create a gt table with grand summary rows
  gt_tbl_2 <-
    na_tbl %>%
    gt(groupname_col = "group") %>%
    grand_summary_rows(
      columns = c(na_1, na_2),
      fns = list(
        ~ sum(., na.rm = TRUE),
        ~ mean(., na.rm = TRUE)
      )
    )

  # Expect the correct values in all of the first and second
  # grand summary rows of `gt_tbl_2`
  gt_tbl_2 %>% render_as_html() %>% xml2::read_html() %>%
    selection_text("[class='gt_row gt_right gt_grand_summary_row gt_first_grand_summary_row']") %>%
    expect_equal(rep("0.00", 2))

  gt_tbl_2 %>% render_as_html() %>% xml2::read_html() %>%
    selection_text("[class='gt_row gt_right gt_grand_summary_row gt_last_summary_row']") %>%
    expect_equal(rep("—", 2))

  # Create a gt table with grand summary rows, replacing missing
  # values with the word "nil"
  gt_tbl_3 <-
    na_tbl %>%
    gt(groupname_col = "group") %>%
    grand_summary_rows(
      columns = c(na_1, na_2),
      fns = list(
        ~ sum(., na.rm = TRUE),
        ~ mean(., na.rm = TRUE)
      ),
      missing_text = "nil"
    )

  # Expect to see the `missing_text` values in all of the second
  # grand summary rows of `gt_tbl_3`
  gt_tbl_3 %>% render_as_html() %>% xml2::read_html() %>%
    selection_text("[class='gt_row gt_right gt_grand_summary_row gt_last_summary_row']") %>%
    expect_equal(rep("nil", 2))

  # Expect an error if summarizing results in a zero-length vector
  expect_error(
    na_tbl %>%
      gt(groupname_col = "group") %>%
      summary_rows(
        groups = "one",
        columns = na_1,
        fns = list(empty = ~ numeric(0))
      )
  )
})

test_that("summary rows can be created when there is no stub", {

  # Create a table based on `sp500`, with
  # four columns of values
  tbl_2 <-
    sp500 %>%
    dplyr::filter(
      date >= "2015-01-05" &
        date <="2015-01-09"
    ) %>%
    dplyr::arrange(date) %>%
    dplyr::select(-adj_close, -volume) %>%
    gt()

  # Create a gt table with a grand summary;
  # the table doesn't have a stub (and there
  # are no row groups)
  gt_tbl <-
    tbl_2 %>%
    summary_rows(
      columns = c(open, high, low, close),
      fns = list(
        average = ~mean(., na.rm = TRUE),
        total = ~sum(., na.rm = TRUE),
        `std dev` = ~sd(., na.rm = TRUE)
      )
    )

  # Expect that the grand summary row labels are
  # available in the rendered output table
  expect_match(
    gt_tbl %>%
      as_raw_html(inline_css = FALSE),
    "<td class=\"gt_row gt_right gt_stub gt_grand_summary_row gt_first_grand_summary_row\">average</td>"
  )

  expect_match(
    gt_tbl %>%
      as_raw_html(inline_css = FALSE),
    "<td class=\"gt_row gt_right gt_stub gt_grand_summary_row\">total</td>"
  )

  expect_match(
    gt_tbl %>%
      as_raw_html(inline_css = FALSE),
    "<td class=\"gt_row gt_right gt_stub gt_grand_summary_row gt_last_summary_row\">std dev</td>"
  )
})

test_that("summary row labels are added in narrow and wide tables", {

  tbl <-
    dplyr::tibble(
      groups = c(rep("one", 5), rep("two", 5)),
      rows = 1:10 %>% as.character(),
      a = 1:10,
      b = 11:20,
      c = 21:30,
      d = 31:40,
      e = 41:50,
      f = 51:60,
      g = 61:70,
      h = 71:80,
      i = 81:90,
      j = 91:100,
      k = 101:110,
      l = 111:120,
      m = 121:130,
      n = 131:140,
      o = 141:150,
      p = 151:160,
      q = 161:170,
      r = 171:180,
      s = 181:190,
      t = 191:200
    )

  # Generate a narrow gt table (4 columns)
  narrow_gt_tbl <-
    tbl %>%
    dplyr::select(c("groups", "rows", letters[1:4])) %>%
    gt(rowname_col = "rows", groupname_col = "groups") %>%
    summary_rows(
      groups = "one",
      columns = letters[1:4],
      fns = list(
        the_sum = ~sum(.),
        mean = ~mean(.)
      )
    ) %>%
    grand_summary_rows(
      columns = letters[1:4],
      fns = list(
        the_sum = ~sum(.),
        mean = ~mean(.)
      )
    ) %>%
    tab_header(
      title = "The Table Title",
      subtitle = "The Table Subtitle"
    ) %>%
    tab_style(
      style = cell_text(align = "left"),
      locations = cells_title(groups = "title")
    ) %>%
    tab_style(
      style = cell_text(align = "left"),
      locations = cells_title(groups = "subtitle")
    )

  # Generate a wide gt table (20 columns)
  wide_gt_tbl <-
    tbl %>%
    dplyr::select(c("groups", "rows", letters[1:(ncol(tbl) - 2)])) %>%
    gt(rowname_col = "rows", groupname_col = "groups") %>%
    summary_rows(
      groups = "one",
      columns = letters[1:(ncol(tbl) - 2)],
      fns = list(
        the_sum = ~sum(.),
        mean = ~mean(.)
      )
    ) %>%
    grand_summary_rows(
      columns = letters[1:(ncol(tbl) - 2)],
      fns = list(
        the_sum = ~sum(.),
        mean = ~mean(.)
      )
    ) %>%
    tab_header(
      title = "The Table Title",
      subtitle = "The Table Subtitle"
    ) %>%
    tab_style(
      style = cell_text(align = "left"),
      locations = cells_title(groups = "title")
    ) %>%
    tab_style(
      style = cell_text(align = "left"),
      locations = cells_title(groups = "subtitle")
    )

  # Expect that the row labels for the groupwise and grand summaries in
  # both tables have `"the_sum"` and `"mean"`
  expect_match(
    narrow_gt_tbl %>%
      as_raw_html(inline_css = FALSE),
    paste0(
      "<td class=\"gt_row gt_right gt_stub gt_summary_row gt_first_summary_row thick\">the_sum</td>.*?",
      "<td class=\"gt_row gt_right gt_stub gt_summary_row gt_last_summary_row\">mean</td>.*?",
      "<td class=\"gt_row gt_right gt_stub gt_grand_summary_row gt_first_grand_summary_row\">the_sum</td>.*?",
      "<td class=\"gt_row gt_right gt_stub gt_grand_summary_row gt_last_summary_row\">mean</td>.*?"
    )
  )

  expect_match(
    wide_gt_tbl %>%
      as_raw_html(inline_css = FALSE),
    paste0(
      "<td class=\"gt_row gt_right gt_stub gt_summary_row gt_first_summary_row thick\">the_sum</td>.*?",
      "<td class=\"gt_row gt_right gt_stub gt_summary_row gt_last_summary_row\">mean</td>.*?",
      "<td class=\"gt_row gt_right gt_stub gt_grand_summary_row gt_first_grand_summary_row\">the_sum</td>.*?",
      "<td class=\"gt_row gt_right gt_stub gt_grand_summary_row gt_last_summary_row\">mean</td>.*?"
    )
  )
})

test_that("extracting a summary from a gt table is possible", {

  # Create a table with summary rows for
  # the `W02` and `W03` groups; the 3 summary
  # rows represent the mean, sum, and standard
  # deviation of all numeric columns; extract
  # the internal summary with `extract_summary()`
  gt_tbl_summary_groupwise <-
    tbl %>%
    summary_rows(
      groups = c("W02", "W03"),
      columns = c(open, high, low, close),
      fns = list(
        average = ~mean(., na.rm = TRUE),
        total = ~sum(., na.rm = TRUE),
        `std dev` = ~sd(., na.rm = TRUE)
      )
    ) %>%
    extract_summary()

  # Expect that the summary object is a list
  expect_type(gt_tbl_summary_groupwise, "list")

  # Expect that the length of the list is `1`
  expect_equal(length(gt_tbl_summary_groupwise), 1)

  # Expect specific names for the list components
  expect_equal(
    names(gt_tbl_summary_groupwise$summary_df_data_list),
    c("W02", "W03")
  )

  # Expect that each component of the list inherits
  # from `tbl_df`
  expect_s3_class(gt_tbl_summary_groupwise$summary_df_data_list[[1]], "tbl_df")
  expect_s3_class(gt_tbl_summary_groupwise$summary_df_data_list[[2]], "tbl_df")

  # Expect specific column names for each of the
  # tibbles in `gt_tbl_summary_groupwise`
  expect_equal(
    names(gt_tbl_summary_groupwise$summary_df_data_list[[1]]),
    c("group_id", "rowname", "date", "open", "high", "low", "close", "week")
  )

  expect_equal(
    names(gt_tbl_summary_groupwise$summary_df_data_list[[2]]),
    c("group_id", "rowname", "date", "open", "high", "low", "close", "week")
  )

  # Expect specific values in each of the tibbles
  expect_equal(
    gt_tbl_summary_groupwise$summary_df_data_list[[1]]$open,
    c(2035.23998, 10176.19990, 23.65756), tolerance = .002
  )

  expect_equal(
    gt_tbl_summary_groupwise$summary_df_data_list[[1]]$high,
    c(2048.56198, 10242.80990, 17.47612), tolerance = .002
  )

  expect_equal(
    gt_tbl_summary_groupwise$summary_df_data_list[[1]]$low,
    c(2016.8540, 10084.2699, 18.5372), tolerance = .002
  )

  expect_equal(
    gt_tbl_summary_groupwise$summary_df_data_list[[1]]$close,
    c(2031.2080, 10156.0400, 22.9171), tolerance = .002
  )

  expect_equal(
    gt_tbl_summary_groupwise$summary_df_data_list[[2]]$open,
    c(2020.42200, 10102.11000, 20.17218), tolerance = .002
  )

  expect_equal(
    gt_tbl_summary_groupwise$summary_df_data_list[[2]]$high,
    c(2033.28798, 10166.43990, 18.33064), tolerance = .002
  )

  expect_equal(
    gt_tbl_summary_groupwise$summary_df_data_list[[2]]$low,
    c(1999.77198, 9998.85990, 15.20847), tolerance = .002
  )

  expect_equal(
    gt_tbl_summary_groupwise$summary_df_data_list[[2]]$close,
    c(2014.9300, 10074.6500, 13.8957), tolerance = .002
  )

  # Create a table with a grand summary; the 3
  # summary rows represent the mean, sum, and
  # standard deviation of all numeric columns;
  # extract the internal summary with `extract_summary()`
  gt_tbl_summary_grand <-
    tbl %>%
    summary_rows(
      columns = c(open, high, low, close),
      fns = list(
        average = ~mean(., na.rm = TRUE),
        total = ~sum(., na.rm = TRUE),
        `std dev` = ~sd(., na.rm = TRUE)
      )
    ) %>%
    extract_summary()

  # Expect that the summary object is a list
  expect_type(gt_tbl_summary_grand, "list")

  # Expect that the length of the list is `1`
  expect_equal(length(gt_tbl_summary_grand), 1)

  # Expect a specific name for the one list component
  expect_equal(names(gt_tbl_summary_grand), "summary_df_data_list")

  # Expect that the single component of the list inherits
  # from `list`
  expect_type(gt_tbl_summary_grand[[1]], "list")

  # Expect specific column names for the
  # tibble in `gt_tbl_summary_grand`
  expect_equal(
    names(gt_tbl_summary_grand$summary_df_data_list[[1]]),
    c("group_id", "rowname", "date", "open", "high", "low", "close", "week")
  )

  # Expect specific values in the tibble
  expect_equal(
    gt_tbl_summary_grand$summary_df_data_list[[1]]$open,
    c(2027.83099, 20278.30990, 22.14929), tolerance = .002
  )

  expect_equal(
    gt_tbl_summary_grand$summary_df_data_list[[1]]$high,
    c(2040.92498, 20409.24980, 18.70516), tolerance = .002
  )

  expect_equal(
    gt_tbl_summary_grand$summary_df_data_list[[1]]$low,
    c(2008.31298, 20083.12980, 18.34602), tolerance = .002
  )

  expect_equal(
    gt_tbl_summary_grand$summary_df_data_list[[1]]$close,
    c(2023.06900, 20230.69000, 19.82022), tolerance = .002
  )
})

test_that("creating summary rows works for hidden columns", {

  # Create a table based on `sp500`, with
  # group names, rownames, and four
  # columns of values; hide the 'open and
  # 'low' columns
  tbl <-
    sp500 %>%
    dplyr::filter(
      date >= "2015-01-05" &
        date <="2015-01-16"
    ) %>%
    dplyr::arrange(date) %>%
    dplyr::mutate(
      week = paste0(
        "W", strftime(date, format = "%V"))
    ) %>%
    dplyr::select(-adj_close, -volume) %>%
    gt(
      rowname_col = "date",
      groupname_col = "week"
    ) %>%
    cols_hide(columns = c(open, low))

  # Extend the gt table with summary rows for
  # the `W02` group, and, don't expect an error
  # even though `summary_rows()` includes hidden
  # columns
  expect_error(
    regexp = NA,
    gt_tbl <-
      tbl %>%
      summary_rows(
        groups = "W02",
        columns = c(open, high, low, close),
        fns = list(
          average = ~mean(., na.rm = TRUE),
          total = ~sum(., na.rm = TRUE),
          `std dev` = ~sd(., na.rm = TRUE)
        )
      )
  )

  # Extract the internal `summary` object
  summary <- dt_summary_get(data = gt_tbl)

  # Expect that the internal `summary` list
  # object has a length of `1` since there was
  # only one call of `summary_rows()`
  length(summary) %>%
    expect_equal(1)

  # For the single list component in `summary`, expect specific
  # names within it
  summary[[1]] %>%
    names() %>%
    expect_equal(
      c(
        "groups", "columns", "fns", "summary_labels",
        "missing_text", "formatter", "formatter_options"
      )
    )

  # Expect the `groups` provided in `summary[[1]]$groups`
  summary[[1]]$groups %>% expect_equal("W02")

  # Expect the `columns` provided in `summary[[1]]$columns`
  summary[[1]]$columns %>% expect_equal(c("open", "high", "low", "close"))

  # Expect that `summary[[1]]$fns` is a `list` object
  summary[[1]]$fns %>% expect_type("list")

  # Expect that the components of `summary[[1]]$fns` are formulas
  summary[[1]]$fns$average %>% expect_s3_class("formula")
  summary[[1]]$fns$total %>% expect_s3_class("formula")
  summary[[1]]$fns$`std dev` %>% expect_s3_class("formula")

  # Expect that `summary[[1]]$missing_text` has a specific value
  summary[[1]]$missing_text %>% expect_equal("---")

  # Expect that `summary[[1]]$formatter` is a `function` object
  expect_equal(class(summary[[1]]$formatter), "function")

  # Expect that `summary[[1]]$formatter_options` is a list
  summary[[1]]$formatter_options %>% expect_type("list")

  # Expect that `summary[[1]]$formatter_options` is
  # of length 0
  summary[[1]]$formatter_options %>% length() %>% expect_equal(0)

  # Extract the summary from `gt_tbl` and obtain the
  # tibble containing the summary for the `W02` group
  summary_extract <- gt::extract_summary(gt_tbl)
  summary_w02 <- summary_extract$summary_df_data_list$W02

  # Expect that all columns are present in `summary_w02`
  expect_equal(
    colnames(summary_w02),
    c(
      "group_id", "rowname",
      "date", "open", "high", "low", "close", "week"
    )
  )

  # Expect non-NA values in all columns that had
  # summaries computed
  expect_true(!any(is.na(summary_w02$open)))
  expect_true(!any(is.na(summary_w02$high)))
  expect_true(!any(is.na(summary_w02$low)))
  expect_true(!any(is.na(summary_w02$close)))

  # TODO: test gt table for values and expect that
  # when `cols_unhide()`ing 'open' and 'low' their summary
  # data will be displayed
})

test_that("Situtations where `rowname` is a column name don't interfere with internals", {

  local_edition(3)
  skip_on_cran()

  # The most basic table where rowname exists as a column; by default
  # a `"rowname"` column is used as the stub
  summary_tbl_1 <-
    exibble %>%
    dplyr::rename(rowname = row) %>%
    gt() %>%
    grand_summary_rows(
      columns = c(num, currency),
      fns = list(
        min = ~min(., na.rm = TRUE),
        max = ~max(., na.rm = TRUE),
        avg = ~mean(., na.rm = TRUE)),
      formatter = fmt_number
    )

  # Take snapshots of `summary_tbl_1`
  summary_tbl_1 %>% render_as_html() %>% expect_snapshot()
  summary_tbl_1 %>% as_latex() %>% as.character() %>% expect_snapshot()
  summary_tbl_1 %>% as_rtf() %>% expect_snapshot()


  # Here the default value of `rowname_col` is set to NULL set that the
  # `"rowname"` col won't be used as the stub; it exists as a visible column
  # and the stub is empty except for the grand summary labels
  summary_tbl_2 <-
    exibble %>%
    dplyr::rename(rowname = row) %>%
    gt(rowname_col = NULL) %>%
    grand_summary_rows(
      columns = c(num, currency),
      fns = list(
        min = ~min(., na.rm = TRUE),
        max = ~max(., na.rm = TRUE),
        avg = ~mean(., na.rm = TRUE)),
      formatter = fmt_number
    )

  # Take snapshots of `summary_tbl_2`
  summary_tbl_2 %>% render_as_html() %>% expect_snapshot()
  summary_tbl_2 %>% as_latex() %>% as.character() %>% expect_snapshot()
  summary_tbl_2 %>% as_rtf() %>% expect_snapshot()


  # Here, the `"rowname"` column is prevented from being used in the stub
  # but the `"group"` column is used to generate row group labels; we have
  # a largely empty stub except for the summary row labels (we can use
  # `summary_rows()` here because of the groupings) and the grand summary
  # row labels
  summary_tbl_3 <-
    exibble %>%
    dplyr::rename(rowname = row) %>%
    gt(rowname_col = NULL, groupname_col = "group") %>%
    summary_rows(
      columns = c(num, currency),
      groups = c("grp_a", "grp_b"),
      fns = list(
        median = ~median(., na.rm = TRUE)
      ),
      formatter = fmt_number
    ) %>%
    grand_summary_rows(
      columns = c(num, currency),
      fns = list(
        min = ~min(., na.rm = TRUE),
        max = ~max(., na.rm = TRUE),
        avg = ~mean(., na.rm = TRUE)),
      formatter = fmt_number
    )

  # Take snapshots of `summary_tbl_3`
  summary_tbl_3 %>% render_as_html() %>% expect_snapshot()
  summary_tbl_3 %>% as_latex() %>% as.character() %>% expect_snapshot()
  summary_tbl_3 %>% as_rtf() %>% expect_snapshot()


  # This table has a stub with values but it is utilizing the `"char"`
  # column for its labels (`"rowname"` and `"group"` are visible columns)
  summary_tbl_4 <-
    exibble %>%
    dplyr::rename(rowname = row) %>%
    gt(rowname_col = "char") %>%
    grand_summary_rows(
      columns = c(num, currency),
      fns = list(
        min = ~min(., na.rm = TRUE),
        max = ~max(., na.rm = TRUE),
        avg = ~mean(., na.rm = TRUE)),
      formatter = fmt_number
    )

  # Take snapshots of `summary_tbl_4`
  summary_tbl_4 %>% render_as_html() %>% expect_snapshot()
  summary_tbl_4 %>% as_latex() %>% as.character() %>% expect_snapshot()
  summary_tbl_4 %>% as_rtf() %>% expect_snapshot()


  # This table is a slight modification on `summary_tbl_4` in that the
  # `"group"` column is being used to generate row groups
  summary_tbl_5 <-
    exibble %>%
    dplyr::rename(rowname = row) %>%
    gt(rowname_col = "char", groupname_col = "group") %>%
    summary_rows(
      columns = c(num, currency),
      groups = c("grp_a", "grp_b"),
      fns = list(
        median = ~median(., na.rm = TRUE)
      ),
      formatter = fmt_number
    ) %>%
    grand_summary_rows(
      columns = c(num, currency),
      fns = list(
        min = ~min(., na.rm = TRUE),
        max = ~max(., na.rm = TRUE),
        avg = ~mean(., na.rm = TRUE)),
      formatter = fmt_number
    )

  # Take snapshots of `summary_tbl_5`
  summary_tbl_5 %>% render_as_html() %>% expect_snapshot()
  summary_tbl_5 %>% as_latex() %>% as.character() %>% expect_snapshot()
  summary_tbl_5 %>% as_rtf() %>% expect_snapshot()


  # This table uses the `"rowname"` column to generate rownames in the stub,
  # and, the `"group"` column is used to form row groups
  summary_tbl_6 <-
    exibble %>%
    dplyr::rename(rowname = row) %>%
    gt(rowname_col = "rowname", groupname_col = "group") %>%
    summary_rows(
      columns = c(num, currency),
      groups = c("grp_a", "grp_b"),
      fns = list(
        median = ~median(., na.rm = TRUE)
      ),
      formatter = fmt_number
    ) %>%
    grand_summary_rows(
      columns = c(num, currency),
      fns = list(
        min = ~min(., na.rm = TRUE),
        max = ~max(., na.rm = TRUE),
        avg = ~mean(., na.rm = TRUE)),
      formatter = fmt_number
    )

  # Take snapshots of `summary_tbl_6`
  summary_tbl_6 %>% render_as_html() %>% expect_snapshot()
  summary_tbl_6 %>% as_latex() %>% as.character() %>% expect_snapshot()
  summary_tbl_6 %>% as_rtf() %>% expect_snapshot()


  # We should expect no errors or warnings when rendering each of these
  # tables to the different output formats
  expect_error(regexp = NA, summary_tbl_1 %>% render_as_html())
  expect_error(regexp = NA, summary_tbl_1 %>% as_latex())
  expect_error(regexp = NA, summary_tbl_1 %>% as_rtf())
  expect_warning(regexp = NA, summary_tbl_1 %>% render_as_html())
  expect_warning(regexp = NA, summary_tbl_1 %>% as_latex())
  expect_warning(regexp = NA, summary_tbl_1 %>% as_rtf())

  expect_error(regexp = NA, summary_tbl_2 %>% render_as_html())
  expect_error(regexp = NA, summary_tbl_2 %>% as_latex())
  expect_error(regexp = NA, summary_tbl_2 %>% as_rtf())
  expect_warning(regexp = NA, summary_tbl_2 %>% render_as_html())
  expect_warning(regexp = NA, summary_tbl_2 %>% as_latex())
  expect_warning(regexp = NA, summary_tbl_2 %>% as_rtf())

  expect_error(regexp = NA, summary_tbl_3 %>% render_as_html())
  expect_error(regexp = NA, summary_tbl_3 %>% as_latex())
  expect_error(regexp = NA, summary_tbl_3 %>% as_rtf())
  expect_warning(regexp = NA, summary_tbl_3 %>% render_as_html())
  expect_warning(regexp = NA, summary_tbl_3 %>% as_latex())
  expect_warning(regexp = NA, summary_tbl_3 %>% as_rtf())

  expect_error(regexp = NA, summary_tbl_4 %>% render_as_html())
  expect_error(regexp = NA, summary_tbl_4 %>% as_latex())
  expect_error(regexp = NA, summary_tbl_4 %>% as_rtf())
  expect_warning(regexp = NA, summary_tbl_4 %>% render_as_html())
  expect_warning(regexp = NA, summary_tbl_4 %>% as_latex())
  expect_warning(regexp = NA, summary_tbl_4 %>% as_rtf())

  expect_error(regexp = NA, summary_tbl_5 %>% render_as_html())
  expect_error(regexp = NA, summary_tbl_5 %>% as_latex())
  expect_error(regexp = NA, summary_tbl_5 %>% as_rtf())
  expect_warning(regexp = NA, summary_tbl_5 %>% render_as_html())
  expect_warning(regexp = NA, summary_tbl_5 %>% as_latex())
  expect_warning(regexp = NA, summary_tbl_5 %>% as_rtf())

  expect_error(regexp = NA, summary_tbl_6 %>% render_as_html())
  expect_error(regexp = NA, summary_tbl_6 %>% as_latex())
  expect_error(regexp = NA, summary_tbl_6 %>% as_rtf())
  expect_warning(regexp = NA, summary_tbl_6 %>% render_as_html())
  expect_warning(regexp = NA, summary_tbl_6 %>% as_latex())
  expect_warning(regexp = NA, summary_tbl_6 %>% as_rtf())
})
